package main

import (
	"fmt"
	_ "unsafe" // 前面加 _ 表示忽略不用的包
)

/*
注意！！！
	值类型：基本数据类型int系列、float系列、bool、string、数组、结构体
	引用类型：指针、slice切片、map、管道、interface等
*/

//演示golang中string转成基本数据类型
func main() {

	var i int = 100
	fmt.Printf("&i = %v\n", &i) //&i = 0xc00004e058

	// 1. ptr 是一个指针变量
	// 2. ptr 的类型是 *int
	// 3. ptr 的值是 &i （i变量的地址）
	var ptr *int = &i
	fmt.Printf("ptr = %v\n", ptr)   //ptr = 0xc00004e058
	fmt.Printf("&ptr = %v\n", &ptr) //&ptr = 0xc000076020
	fmt.Printf("*ptr = %v\n", *ptr) //*ptr = 100

	// 指针必须有地址值否则是个野指针，运行时会报错
	var ptr2 *int64
	// *ptr2 = 1000                     // 没有地址的指针无法赋值，编译没问题，运行报错
	fmt.Printf("*ptr2 = %v\n", ptr2) // <nil>
	// fmt.Printf("*ptr2 = %v\n", *ptr2) // 编译能通过，但是运行报错
	var i64 int64 = 1000
	ptr2 = &i64                                                         // 可以重新给复制一个地址
	fmt.Printf("*ptr2 = %v, &i64 = %v, ptr2 = %v\n", *ptr2, &i64, ptr2) //*ptr2 = 1000, &i64 = 0xc0000120c8, ptr2 = 0xc0000120c8
	// var i2 int8 = 10
	// ptr2 = &i2 // 指针不能够接收不同类型的变量的值

	fmt.Println("*****************")
	/*
		当指针指向一个对象类型的时候直接输出 ptr 是该对象值的 &对象
	*/
	arr := [3]int{1, 2, 3}
	var pa *[3]int = &arr
	fmt.Printf("&arr = %v\n", &arr)                           //&arr = &[1 2 3]
	fmt.Printf("pa = %v, &pa = %v, *pa = %v\n", pa, &pa, *pa) //pa = &[1 2 3], &pa = 0xc000006038, *pa = [1 2 3]

}
